#ifndef CASEDB_RECORDSET_HPP
#define CASEDB_RECORDSET_HPP

#include "CaseDB/CaseDbConfig.hpp"
#include "CaseDB/DbTypes.hpp"
#include <boost/any.hpp>
#include <vector>
#include <list>

namespace CaseDB
{

/// \ingroup CaseDB
/// \brief It implements a record set that will be used to store the results of a query execution.
///
/// A record set contains a metadata (description of the types of columns) and a collection of records. The metadata is 
///	used by the statement execution logic to convert from database framework specific variant type to boost::any that 
///	this class uses for keeping the database values. The metadata can also be used for conversion later, from boost::any 
///	to the needed types, while using the data enclosed in this record set.
class CASEDB_API RecordSet
{
public:
	/// \brief Metadata of the record set.
	typedef std::vector< DbTypes> Metadata;

	/// \brief A record in the record set.
	typedef std::vector< boost::any> Record;

	/// \brief The record set.
	typedef std::list< Record> RecordCollection;

	/// \brief The iterator to be used to iterate through the records.
	typedef RecordCollection::const_iterator ConstRecordIterator;

	/// \brief It initializes the recordset.
	/// \param mt the metadata of the record set.
	RecordSet( const Metadata& mt);

	/// \brief It gets the metadata of the record set.
	const Metadata& metadata() const { return metaData_; }

	/// \brief It gets the iterator to the first record in the set.
	ConstRecordIterator begin() const { return results_.begin(); }

	/// \brief It gets the iterator to the end of the record set.
	ConstRecordIterator end() const { return results_.end(); }

	/// \brief It appends a new record.
	/// \pre the number of fields in the new record is equal to the number of fields in the metadata.
	void appendRecord( const Record& newRec);

	/// \brief It gets the number of records in the record set.
	std::size_t numberOfRecords() const { return results_.size(); }

private:
	Metadata metaData_;
	RecordCollection results_;
};

} // namespace CaseDB

#endif // CASEDB_RECORDSET_HPP
